package eteam.aps.service.impl;

import eteam.aps.api.U8Api;
import eteam.aps.common.anno.ExcelExport;
import eteam.aps.common.constant.InsType;
import eteam.aps.common.constant.QCAcceptType;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.common.helper.JsonPage;
import eteam.aps.mapper.ArrivalVouchMapper;
import eteam.aps.mapper.ExportMapper;
import eteam.aps.mapper.ExportSelectorMapper;
import eteam.aps.model.dto.ArrivalVouchQueryDto;
import eteam.aps.model.dto.SaleQueryDto;
import eteam.aps.model.entity.arrival.ArrivalVouch;
import eteam.aps.model.export.model.*;
import eteam.aps.model.export.query.*;
import eteam.aps.service.ExportService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;

/**
 * @author Ll
 * @since 2024/1/17
 */
@SuppressWarnings("DuplicatedCode")
@Service
@AllArgsConstructor
public class ExportServiceImpl implements ExportService {

    private ExportMapper exportMapper;

    private ExportSelectorMapper exportSelectorMapper;

    @Override
    @ExcelExport(head = ArrivalVouchExport.class, fileName = "到货单", sheet = "到货单查询")
    public List<ArrivalVouchExport> arrivalVouchExport(Map<String, String> user, ArrivalVouchQueryDto arrivalVouchQueryDto) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("fState", ParentEntity.FSTATE_DELETED);
        // 条码号
        if (Helper.isNotEmpty(arrivalVouchQueryDto.getfBarCode()))
            map.put("fBarCode", arrivalVouchQueryDto.getfBarCode());
        // 工单号
        if (Helper.isNotEmpty(arrivalVouchQueryDto.getfCCode())) map.put("fCode", arrivalVouchQueryDto.getfCCode());
        // 品号
        if (Helper.isNotEmpty(arrivalVouchQueryDto.getFclnvCode()))
            map.put("fInvCode", arrivalVouchQueryDto.getFclnvCode());
        // 物料名称
        if (Helper.isNotEmpty(arrivalVouchQueryDto.getfProductName()))
            map.put("fProductName", Helper.likeSql(arrivalVouchQueryDto.getfProductName()));
        // 物料规格
        if (Helper.isNotEmpty(arrivalVouchQueryDto.getFclnvStd()))
            map.put("fInvStd", Helper.likeSql(arrivalVouchQueryDto.getFclnvStd()));
        // 开始时间
        if (arrivalVouchQueryDto.getStartTime() != null) map.put("startTime", arrivalVouchQueryDto.getStartTime());
        // 结束时间
        if (arrivalVouchQueryDto.getEndTime() != null) map.put("endTime", arrivalVouchQueryDto.getEndTime());
        // 验收状态
        if (arrivalVouchQueryDto.getAcceptState() != null)
            map.put("acceptState", arrivalVouchQueryDto.getAcceptState());
        // 出厂检验状态
        if (arrivalVouchQueryDto.getInsType() != null) map.put("insType", arrivalVouchQueryDto.getInsType());
        // 物料分类
        if (arrivalVouchQueryDto.getInvType() != null) map.put("invType", arrivalVouchQueryDto.getInvType());
        // 采购方
        if (arrivalVouchQueryDto.getPurName() != null) map.put("purName", arrivalVouchQueryDto.getPurName());
        List<ArrivalVouchExport> list = exportMapper.arrivalVouchExport(map);
        for (int i = 0; i < list.size(); i++) {
            ArrivalVouchExport data = list.get(i);
            data.setSort(i + 1);
            data.setValidaAcceptType(QCAcceptType.MAP.get(data.getValidaAcceptType()));
            data.setInsType(InsType.MAP.get(data.getInsType()));
            if (Helper.isNotEmpty(data.getDate())) data.setDate(data.getDate().substring(0, 11));
            if (data.getCheckQuantity().toBigInteger().equals(BigInteger.ZERO)) {
                data.setValidRate("100%");
                data.setWeightQty(data.getQuantity());
            } else {
                BigDecimal rate = data.getValidQuantity().divide(data.getCheckQuantity(), 2, RoundingMode.FLOOR);
                data.setValidRate(rate.multiply(new BigDecimal("100")) + "%");
                data.setWeightQty(rate.multiply(data.getQuantity()));
            }
            data.setCreateUser(user.getOrDefault(data.getCreateUser(), data.getCreateUser()));
        }
        return list;
    }

    @Override
    public JsonPage<ProductSerialExport> productSerialJsp(ProductSerialQuery productSerialQuery) {
        int count = exportSelectorMapper.productSerialCount(productSerialQuery);
        if (count < 0) {
            return JsonPage.builder(productSerialQuery.getPage(), productSerialQuery.getSize(), count, Collections.emptyList());
        }
        return JsonPage.builder(productSerialQuery.getPage(), productSerialQuery.getSize(), count, exportSelectorMapper.productSerial(productSerialQuery));
    }

    @Override
    @ExcelExport(head = ProductSerialExport.class, sheet = "任务令产品编码状态清单", fileName = "任务令产品编码状态清单")
    public List<ProductSerialExport> productSerialExport(ProductSerialQuery productSerialQuery) {
        return exportMapper.productSerialExport(productSerialQuery);
    }

    @Override
    public JsonPage<ProductWorkProcessingExport> productWorkProcessingJsp(ProductWorkProcessingQuery processingQuery) {
        int count = exportSelectorMapper.productWorkProcessingCount(processingQuery);
        if (count < 0) {
            return JsonPage.builder(processingQuery.getPage(), processingQuery.getSize(), count, Collections.emptyList());
        }
        return JsonPage.builder(processingQuery.getPage(), processingQuery.getSize(), count, exportSelectorMapper.productWorkProcessing(processingQuery));
    }

    @Override
    @ExcelExport(head = ProductWorkProcessingExport.class, sheet = "任务令产品编码工序状态清单", fileName = "任务令产品编码工序状态清单")
    public List<ProductWorkProcessingExport> productWorkProcessingExport(ProductWorkProcessingQuery processingQuery) {
        return exportMapper.productWorkProcessingExport(processingQuery);
    }

    @Override
    public JsonPage<ProductInvExport> productInvJsp(ProductInvQuery productInvQuery) {
        int count = exportSelectorMapper.productInvJspCount(productInvQuery);
        if (count < 0) {
            return JsonPage.builder(productInvQuery.getPage(), productInvQuery.getSize(), count, Collections.emptyList());
        }
        return JsonPage.builder(productInvQuery.getPage(), productInvQuery.getSize(), count, exportSelectorMapper.productInvJsp(productInvQuery));
    }

    @Override
    @ExcelExport(head = ProductInvExport.class, sheet = "任务令产品材料序列清单", fileName = "任务令产品材料序列清单")
    public List<ProductInvExport> productInvExport(ProductInvQuery productInvQuery) {
        return exportMapper.productInvExport(productInvQuery);
    }

    @Override
    public List<SaleOrderExport> saleOrderExport(SaleQueryDto query) {
        return exportMapper.saleOrderExport(query);
    }

    @Override
    public List<OutboundOrdersExport> outboundOrdersExport(OutboundOrdersQuery query) {
        return exportMapper.outboundOrdersExport(query);
    }

    @Override
    public List<ShipmentDataExport> shipmentDataSelect(ShipmentDataQuery query) {
        return exportMapper.shipmentDataExport(query);
    }

    @Override
    @ExcelExport(head = ShipmentDataExport.class, sheet = "发货数据", fileName = "发货数据")
    public List<ShipmentDataExport> shipmentDataExport(ShipmentDataQuery query) {
        return exportMapper.shipmentDataExport(query);
    }

    @Override
    public List<QualityExport> qualitySelect(QualityQuery query) {
        List<QualityExport> list = exportMapper.qualityExport(query);
        list.forEach(data -> {
            // 设置班次
            Optional.ofNullable(data.getDate())
                    .ifPresent(date -> {
                        int hour = date.getHour();
                        if (hour >= 8 && hour <= 20) {
                            data.setWork("早班");
                        } else {
                            data.setWork("晚班");
                        }
                    });
            // 设置不良数
            Optional.ofNullable(data.getGoodOrNot()).ifPresent(checkNum -> data.setInvalidNum(checkNum ? 0 : data.getCheckNum()));
        });
        return list;
    }

    @Override
    @ExcelExport(head = QualityExport.class, sheet = "质检数据", fileName = "质检数据")
    public List<QualityExport> qualityExport(QualityQuery query) {
        List<QualityExport> list = exportMapper.qualityExport(query);
        list.forEach(data -> {
            // 设置班次
            Optional.ofNullable(data.getDate())
                    .ifPresent(date -> {
                        int hour = date.getHour();
                        if (hour >= 8 && hour <= 20) {
                            data.setWork("早班");
                        } else {
                            data.setWork("晚班");
                        }
                    });
            // 设置不良数
            Optional.ofNullable(data.getGoodOrNot()).ifPresent(checkNum -> data.setInvalidNum(checkNum ? 0 : data.getCheckNum()));
        });
        return list;
    }

    private final ArrivalVouchMapper mapper;

    @Override
    @ExcelExport(head = InventoryExport.class, sheet = "现存量", fileName = "现存量清单")
    public List<InventoryExport> inventoryExport(InventoryQuery query) throws Exception {
        JsonPage<InventoryExport> inventory = U8Api.getInventory(query);
        if (!inventory.getList().isEmpty()) {
            Map<String, ArrivalVouch> arrMap = new HashMap<>();
            mapper.selectArrivalInvAndBatch(query).forEach(
                    data -> arrMap.put(data.getFclnvCode() + data.getfCBatch(), data)
            );
            inventory.getList().forEach(data -> {
                ArrivalVouch arrivalVouch = arrMap.get(data.getInvCode() + data.getBatch());
                if (arrivalVouch != null) {
                    data.setCurrentTime(arrivalVouch.getfLastModifyTime());
                    data.setBarCode(arrivalVouch.getfBarCode());
                }
            });
        }
        return inventory.getList();
    }

    @Override
    public JsonPage<InventoryExport> inventorySelect(InventoryQuery query) throws Exception {
        JsonPage<InventoryExport> inventory = U8Api.getInventory(query);
        if (!inventory.getList().isEmpty()) {
            Map<String, ArrivalVouch> arrMap = new HashMap<>();
            mapper.selectArrivalInvAndBatch(query).forEach(
                    data -> arrMap.put(data.getFclnvCode() + data.getfCBatch(), data)
            );
            inventory.getList().forEach(data -> {
                ArrivalVouch arrivalVouch = arrMap.get(data.getInvCode() + data.getBatch());
                if (arrivalVouch != null) {
                    data.setCurrentTime(arrivalVouch.getfLastModifyTime());
                    data.setBarCode(arrivalVouch.getfBarCode());
                }
            });
        }
        return inventory;
    }

    @Override
    public InvoicesExport deliveryNoteSelect(InvoicesQuery query) {
        InvoicesHead head = exportMapper.deliveryNoticeHead(query);
        if (head == null) {
            throw new BusinessException("单号不存在!");
        }
        List<InvoicesBody> body = exportMapper.deliveryNoticeBody(query);
        // 获取项目名
        if (!body.isEmpty()) {
            head.setProjectName(
                    Optional.ofNullable(body.get(0))
                            .map(InvoicesBody::getProjectName)
                            .orElse(null)
            );
            head.setElectronFlow(
                    Optional.ofNullable(body.get(0))
                            .map(InvoicesBody::getElectronFlow)
                            .orElse(null)
            );
        }
        InvoicesExport export = new InvoicesExport();
        export.setHead(head);
        export.setBody(body);
        return export;
    }
}
